package com.chenl.interview.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chenl.interview.common.*;
import com.chenl.interview.constant.UserConstant;
import com.chenl.interview.exception.BusinessException;
import com.chenl.interview.model.dto.questionBank.QuestionBankAddRequest;
import com.chenl.interview.model.dto.questionBank.QuestionBankQueryRequest;
import com.chenl.interview.model.entity.QuestionBank;
import com.chenl.interview.model.vo.QuestionBankVO;
import com.chenl.interview.model.vo.QuestionVO;
import com.chenl.interview.service.QuestionBankService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/questionBank")
@Api
@Slf4j
public class QuestionBankController {
    @Autowired
    private QuestionBankService questionBankService;

    // TODO: 2025/1/2 创建题库（仅管理员）
    @PostMapping("/add")
    @SaCheckRole(value = UserConstant.ADMIN_ROLE)
    @ApiOperation(value = "创建题库")
    public BaseResponse<Long> addQuestionBank(@RequestBody QuestionBankAddRequest questionBankAddRequest){
        if (questionBankAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        Long id = questionBankService.addQuestionBank(questionBankAddRequest);
        if (id == null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }

        return ResultUtils.success(id);
    }

    // TODO: 2025/1/2 编辑题库（仅管理员）

    // TODO: 2025/1/2 删除题库，以及删除绑定的题库题目关系（仅管理员）
    @PostMapping("/delete")
    @SaCheckRole(value = UserConstant.ADMIN_ROLE)
    @ApiOperation(value = "删除题库")
    public BaseResponse<Boolean> deleteQuestionBank(@RequestBody DeleteRequest deleteRequest){
        ThrowUtils.throwIf(deleteRequest == null,ErrorCode.PARAMS_ERROR);

        Boolean result = questionBankService.deleteQuestionBank(deleteRequest);
        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return ResultUtils.success(result);
    }
    // TODO: 2025/1/2 分页获取题库信息（仅管理员）

    // TODO: 2025/1/2 分页获取题库封装
    @PostMapping("/list/page/vo")
    @SaCheckLogin
    @ApiOperation(value = "分页获取题库封装类")
    @SentinelResource(value = "listQuestionBankVOByPage",blockHandler = "handleBlockException",fallback = "handleFallback")
    public BaseResponse<Page<QuestionBankVO>> listQuestionBankVOByPage(@RequestBody QuestionBankQueryRequest questionBankQueryRequest){
        //参数检验
        ThrowUtils.throwIf(questionBankQueryRequest == null,ErrorCode.PARAMS_ERROR);

        int current = questionBankQueryRequest.getCurrent();
        int pageSize = questionBankQueryRequest.getPageSize();

        QueryWrapper<QuestionBank> queryWrapper = questionBankService.getQueryWrapper(questionBankQueryRequest);
        Page<QuestionBank> page = questionBankService.page(new Page<>(current, pageSize), queryWrapper);

        return ResultUtils.success(questionBankService.getQuestionBankVOPage(page));
    }

    /**
     * listQuestionBankVOByPage 流控操作
     * 限流：提示“系统压力过大，请耐心等待”
     * 熔断：执行降级操作
     */
    public BaseResponse<Page<QuestionVO>> handleBlockException(@RequestBody QuestionBankQueryRequest questionBankQueryRequest, BlockException ex) {
        // 降级操作
        if (ex instanceof DegradeException) {
            return handleFallback(questionBankQueryRequest, ex);
        }
        // 限流操作
        return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统压力过大，请耐心等待");
    }
    /**
     * listQuestionBankVOByPage 降级操作：直接返回本地数据
     */
    public BaseResponse<Page<QuestionVO>> handleFallback(@RequestBody QuestionBankQueryRequest questionBankQueryRequest, Throwable ex) {
        // 可以返回本地数据或空数据
        return ResultUtils.success(null);
    }


    @PostMapping("get/vo")
    @SaCheckLogin
    @ApiOperation(value = "根据id获取题库封装类")
    public BaseResponse<QuestionBankVO> getQuestionBankVOById(@RequestBody QuestionBankQueryRequest questionBankQueryRequest){
        ThrowUtils.throwIf(questionBankQueryRequest == null,ErrorCode.PARAMS_ERROR);
        ThrowUtils.throwIf(questionBankQueryRequest.getId() < 0,ErrorCode.PARAMS_ERROR);

        QuestionBankVO questionBankVO = questionBankService.getQuestionBankVO(questionBankQueryRequest);
        ThrowUtils.throwIf(questionBankVO == null,ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(questionBankVO);
    }

}
